package com.example.demo.T1.V1;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * T1..
 *
 * @author Lizhong
 * @date 2020/8/18
 */
public class T1 {


    public static void main(String[] args) {

    }

    /**
     * 严格区分"null"与null
     *
     * key1="null";
     * key2=null;
     *
     * key1!=key2;
     *
     * @param arrProA
     * @param arrProB
     * @return
     */
    static String SPLITER = ",";

    public static MergedAB[] merge(ProA[] arrProA, ProB[] arrProB) {
        //尽量采用较低的时间复杂度和空间复杂度来实现

        if (arrProA == null || arrProA.length == 0 || arrProB == null || arrProB.length == 0) {
            return new MergedAB[0];
        }
        // k1!=null && k2!=null
        Map<String, List<ProA>> k1AndK2ProAMap = new HashMap<>();

        // k1==null && k2!=null
        Map<String, List<ProA>> k1IsNullProAMap = new HashMap<>();

        // k1!=null && k2==null
        Map<String, List<ProA>> k2IsNullProAMap = new HashMap<>();

        // k1==null && k2==null
        List<ProA> k1AndK2IsNullProAList = new ArrayList<>();


        for (ProA proA : arrProA) {
            if (proA == null) continue;
            /*
             * 连接key用分割 解决pA.key1 = "ab" pA.key2="cd"  ;pB.key1 = "a" pB.key2="bcd"
             */
            if (proA.key1 != null && proA.key2 != null) {
                k1AndK2ProAMap.computeIfAbsent(proA.key1 + SPLITER + proA.key2, k -> new ArrayList<>()).add(proA);
                // key1==null && key==null
            } else if (proA.key1 == null && proA.key2 == null) {
                k1AndK2IsNullProAList.add(proA);
                // key1==null
            } else if (proA.key1 == null) {
                k1IsNullProAMap.computeIfAbsent(proA.key2, k -> new ArrayList<>()).add(proA);
                // key2==null
            } else {
                k2IsNullProAMap.computeIfAbsent(proA.key1, k -> new ArrayList<>()).add(proA);
            }

        }

        List<MergedAB> mergedABList = new ArrayList<>();
        for (ProB proB : arrProB) {
            if (proB == null) continue;
            ProA proA = null;
            if (proB.key1 != null && proB.key2 != null) {

                List<ProA> proAS = k1AndK2ProAMap.get(proB.key1 + SPLITER + proB.key2);
                if (proAS == null || proAS.isEmpty()) continue;
                proA = proAS.remove(0);
            } else if (proB.key1 == null && proB.key2 == null) {

                if (k1AndK2IsNullProAList.isEmpty()) continue;
                proA = k1AndK2IsNullProAList.remove(0);
            } else if (proB.key1 == null) {

                List<ProA> proAS = k1IsNullProAMap.get(proB.key2);
                if (proAS == null || proAS.isEmpty()) continue;
                proA = proAS.remove(0);

            } else {

                List<ProA> proAS = k2IsNullProAMap.get(proB.key1);
                if (proAS == null || proAS.isEmpty()) continue;
                proA = proAS.remove(0);

            }

            MergedAB e = new MergedAB();
            e.key1 = proA.key1;
            e.key2 = proA.key2;
            e.v1 = proA.v1;
            e.v2 = proB.v2;
            mergedABList.add(e);
        }

        MergedAB[] mergedABS1 = new MergedAB[mergedABList.size()];
        mergedABList.toArray(mergedABS1);
        return mergedABS1;
    }

}


